package cc.rengu.igas.bomp.core.service.trans;


import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.constant.BompTreeNodeConstant;
import cc.rengu.igas.bomp.common.constant.DubboMethodConstant;
import cc.rengu.igas.bomp.common.constant.TableNameConstant;
import cc.rengu.igas.bomp.common.dao.*;
import cc.rengu.igas.bomp.common.dao.impl.*;
import cc.rengu.igas.bomp.common.entity.*;
import cc.rengu.igas.bomp.common.enums.*;
import cc.rengu.igas.bomp.common.util.ChangeNextStatusUtil;
import cc.rengu.igas.bomp.common.util.CompareFieldsUtil;
import cc.rengu.igas.bomp.common.util.InitParamUtil;
import cc.rengu.igas.bomp.core.model.UserSessionInfo;
import cc.rengu.igas.bomp.core.realize.MchntVerifyService;
import cc.rengu.igas.bomp.core.realize.impl.MchntVerifyServiceImpl;
import cc.rengu.igas.bomp.core.service.base.AuditService;
import cc.rengu.igas.bomp.facade.bean.*;
import cc.rengu.igas.bomp.facade.enums.BompManageOprTypeEnum;
import cc.rengu.igas.bomp.facade.enums.BompMchntNatureEnum;
import cc.rengu.igas.bomp.facade.enums.BompMchntStatusEnum;
import cc.rengu.igas.bomp.facade.enums.BompSettleTypeEnum;
import cc.rengu.igas.bomp.facade.request.MchntSettleInfoManageRequest;
import cc.rengu.igas.bomp.facade.response.MchntSettleInfoManageResponse;
import cc.rengu.igas.share.common.enums.SettleAcctTypeEnum;
import cc.rengu.igas.share.common.util.GlobalEsbUtil;
import cc.rengu.igas.smps.facade.base.Header;
import cc.rengu.igas.smps.facade.request.BankAcctInfoQueryRequest;
import cc.rengu.igas.smps.facade.response.BankAcctInfoQueryResponse;
import cc.rengu.igas.smps.facade.result.Result;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.entity.BinInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商户结算信息管理
 */
public class MchntSettleInfoManageService extends AuditService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        MchntSettleInfoManageRequest request = new MchntSettleInfoManageRequest();
        ConvertUtil.convertOutput(request);
        return request;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MchntSettleInfoManageRequest manageRequest = (MchntSettleInfoManageRequest) request;
        BizResponse<MchntSettleInfoManageResponse> bizResponse = new BizResponse<>();
        MchntSettleInfoManageResponse mchntSettleInfoManageResponse = new MchntSettleInfoManageResponse();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = manageRequest.getHeader().getInstId();
        String mchntNo = manageRequest.getMchntNo();
        rglog.debug("MchntSettleInfoManageRequest:{}", JSONObject.toJSONString(manageRequest));
        MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
        //查询商户信息
        MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(instId, mchntNo);
        if (null == mchntBaseInfo) {
            rglog.error("管理商户结算信息失败, 根据商户号查询商户基本信息为空，instId:{},mchntNo:{}", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }

        if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntBaseInfo.getMchntType())
                && AppParamConstant.NO.equals(mchntBaseInfo.getIndependentDataFlag())) {
            //连锁商户门店 非独立维护
            rglog.error("管理商户结算信息失败, 根据商户号查询商户基本信息为连锁商户门店且非独立维护，沿用上级结算账户信息不需要设置结算信息，instId:{},mchntNo:{}", instId, mchntNo);
            throw new BizException(RespCodeEnum.NOT_ALLOW_TO_SET_ACCT_INFO.getRespCode(), RespCodeEnum.NOT_ALLOW_TO_SET_ACCT_INFO.getRespDesc());
        }

        if (BompMchntStatusEnum.CANCEL.getType().equals(mchntBaseInfo.getMchntStatus())) {
            rglog.error("管理商户结算信息失败, 根据商户号查询商户状态为已注销，instId:{},mchntNo:{}", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_CANCEL.getRespCode(), RespCodeEnum.MCHNT_CANCEL.getRespDesc());
        }

        List<SettleAcctInfoBean> settleAcctInfoBeanList = manageRequest.getSettleAcctInfoBeanList();
        if (CollectionUtils.isEmpty(settleAcctInfoBeanList)) {
            rglog.error("管理商户结算信息失败, 结算信息参数为空！，instId:{},mchntNo:{}", instId, mchntNo);
            throw new BizException(RespCodeEnum.PARAM_ERROR.getRespCode(), RespCodeEnum.PARAM_ERROR.getRespDesc());
        }

        MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
        MchntSignInfo mchntSignInfo = mchntSignInfoMapper.selectMchntSignInfoByPrimaryKey(instId, mchntNo);
        if (null == mchntSignInfo) {
            rglog.error("管理商户签约信息失败, 根据商户号查询商户签约信息为空，instId:{},mchntNo:{}", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        xmlTreeUtil.setXmlTreeObjectValue(BompTreeNodeConstant.MCHNT_SIGN_INFO, mchntSignInfo);

        String channelId = manageRequest.getHeader().getChanlId();
        if ("WECHAT".equals(channelId) || "MOBILE".equals(channelId) || "APP".equals(channelId) || "PCWEB".equals(channelId)) {
            //解密敏感信息
            String sessionObjStr = RedisUtil.onceGet(manageRequest.getHeader().getSession());
            UserSessionInfo userSessionInfo = JSON.parseObject(sessionObjStr, UserSessionInfo.class);
            for (SettleAcctInfoBean settleAcctInfoBean : settleAcctInfoBeanList) {
                settleAcctInfoBean.setSettleAcctNo(descriptData(userSessionInfo.getSensitiveKey(), settleAcctInfoBean.getSettleAcctNo()));
            }
        }

        SysParamService sysParamService = new SysParamServiceImpl();
        SysParamMapper sysParamMapper = new SysParamMapperImpl();
        MchntVerifyService mchntVerifyService = new MchntVerifyServiceImpl();

        /*获取卡类型-本行/他行*/
        BompAcctIssuerQueryMapper acctIssuerQueryMapper = new BompAcctIssuerQueryMapperImpl();
        for (int i = 0; i < manageRequest.getSettleAcctInfoBeanList().size(); i++) {
            BinInfo binInfo = acctIssuerQueryMapper.selectBinInfo(manageRequest.getSettleAcctInfoBeanList().get(i).getSettleAcctNo());
            if (null != binInfo) {
                //查询该法人行的银联机构号`
                SysParam sysParam = sysParamService.getSysParamInfo(instId, BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.CUPS_INSR_ID);
                if (binInfo.getIssuerCode().substring(0, 4).equals(sysParam.getParamValue().substring(0, 4))) {
                    /* 本行卡 */
                    xmlTreeUtil.setXmlTreeStringValue(BompTreeNodeConstant.SETTLE_ACCT_TYPE_FLAG + i, BompAppParamConstant.FLAG_Y);
                } else {
                    /*他行卡*/
                    xmlTreeUtil.setXmlTreeStringValue(BompTreeNodeConstant.SETTLE_ACCT_TYPE_FLAG + i, BompAppParamConstant.FLAG_N);
                }
            } else {
                rglog.error("获取卡BIN信息失败,卡号<{}>", manageRequest.getSettleAcctInfoBeanList().get(i).getSettleAcctNo());
                /* 可能是本行内部户或存折,记为本行卡 */
                xmlTreeUtil.setXmlTreeStringValue(BompTreeNodeConstant.SETTLE_ACCT_TYPE_FLAG + i, BompAppParamConstant.FLAG_N);
            }
        }


        if (BompManageOprTypeEnum.CREATE.getType().equals(manageRequest.getOprType())) {
            if (null != manageRequest.getCashWithdrawalFeeInfoBean()
                    && !StringUtil.isEmptyOrNull(manageRequest.getCashWithdrawalFeeInfoBean().getFeeCode())) {
                rglog.error("管理商户结算信息失败, 新增时不允许增加提现费率，instId:{},mchntNo:{}", instId, mchntNo);
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }

            //新增商户结算信息
            increaseMchntSettleInfo(manageRequest, xmlTreeUtil, mchntBaseInfo, mchntSignInfo);
        } else if (BompManageOprTypeEnum.MODIFY.getType().equals(manageRequest.getOprType())) {
            //修改商户结算信息
            modifyMchntSettleInfoHandle(xmlTreeUtil, manageRequest, mchntBaseInfo, mchntSignInfo);
        } else {
            //审核商户结算信息
            rglog.error("不允许单个页面进行审核操作！instId:{},前端流水号:{}",
                    manageRequest.getHeader().getInstId(), manageRequest.getHeader().getTraceNo());
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        mchntSettleInfoManageResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        mchntSettleInfoManageResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mchntSettleInfoManageResponse);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        return bizResponse;
    }

    /**
     * 检查不允许的账号等级类型
     *
     * @param doesAcctTypeSysParamParamValue 不允许账号等级列表【02,03】
     * @param acctNo                         结算账号
     * @throws Exception 异常
     */
    private void checkDoesAcctTyepe(String doesAcctTypeSysParamParamValue, String acctNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String[] acctTypeArray = doesAcctTypeSysParamParamValue.split(AppParamConstant.DEFAULT_DELIMITER);
        String acctLevel = "";
        Result<BankAcctInfoQueryResponse> result = coreAcctInfoQuery(acctNo, instId);
        if (null == result || null == result.getResult()) {
            rglog.error("调用通道查询账户信息失败");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        } else if (!result.isSuccess() || !DubboMethodConstant.DUBBO_SUCCESS.equals(result.getResult().getRespCode())) {
            rglog.error("调用通道查询账户信息失败");
            throw new BizException(result.getResult().getRespCode(), result.getResult().getRespDesc());
        } else {
            //交易成功
            acctLevel = result.getResult().getAcctLevel();
        }

        /*检查账号类型是否属于所配置的不允许账号类型*/
        for (String acctType : acctTypeArray) {
            if (acctType.equals(acctLevel)) {
                rglog.error("结算账号<{}>类型<{}>存在不允许的账号类型列表<{}>中,校验不通过.", acctNo, acctLevel, doesAcctTypeSysParamParamValue);
                throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
            }
        }
    }

    private Result<BankAcctInfoQueryResponse> coreAcctInfoQuery(String acctNo, String instId) throws Exception {
        /*获取账号等级*/
        BankAcctInfoQueryRequest coreAcctInfoQueryRequest = new BankAcctInfoQueryRequest();
        Header acctInfoHeader = new Header();
        acctInfoHeader.setInstId(instId);
        acctInfoHeader.setSrcSysId(AppParamConstant.SYS_ID);
        acctInfoHeader.setChanlId(ChannelEnum.BSPS.getChannelType());
        acctInfoHeader.setTransDate(DateUtil.getCurrentDate());
        acctInfoHeader.setTransTime(DateUtil.getCurrentTime());
        acctInfoHeader.setVersion("1.0.0");
        acctInfoHeader.setBizType("00");
        acctInfoHeader.setTxnNum("00010000200000");
        acctInfoHeader.setTraceNo(GlobalEsbUtil.generateEsbSeqeuenceNumber(instId));
        coreAcctInfoQueryRequest.setAcctNo(acctNo);
        coreAcctInfoQueryRequest.setHeader(acctInfoHeader);
        DubboService dubboService = new DubboServiceImpl();
        return (Result<BankAcctInfoQueryResponse>) dubboService.callDubboService(DubboMethodConstant.DUBBO_BANK_SUP_SERVICE, "bankAcctInfoQuery", coreAcctInfoQueryRequest);
    }

    private void modifyMchntSettleInfoHandle(XmlTreeUtil xmlTreeUtil,
                                             MchntSettleInfoManageRequest request,
                                             MchntBaseInfo mchntBaseInfo,
                                             MchntSignInfo mchntSignInfo) throws Exception {


        //判断当前状态是否允许修改
        if (!ChangeNextStatusUtil.isAllowModifyData(mchntBaseInfo.getAuditStatus())) {
            rglog.error("修改商户结算信息失败, 当前商户基本信息待审核，不允许修改，instId:{},mchntNo:{},当前商户审核状态:{}",
                    mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo(), mchntBaseInfo.getAuditStatus());
            throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
        }

        if (AuditStatusEnum.BE_AUDIT.getAuditStatus().equals(mchntBaseInfo.getAuditStatus())
                || AuditStatusEnum.ADD_AUDIT_REJECT.getAuditStatus().equals(mchntBaseInfo.getAuditStatus())) {
            //新增草稿状态修改或新增审核失败修改 -> 提交待审核
            modifyAcctInfoByCreateProcessing(xmlTreeUtil, request, mchntBaseInfo, mchntSignInfo);
        } else {
            modifyMchntSettleInfo(xmlTreeUtil, request, mchntBaseInfo, mchntSignInfo);
        }

    }

    private void modifyMchntSettleInfo(XmlTreeUtil xmlTreeUtil,
                                       MchntSettleInfoManageRequest request,
                                       MchntBaseInfo mchntBaseInfo,
                                       MchntSignInfo mchntSignInfo) throws Exception {
        String auditStatus = AuditStatusEnum.MODIFY_BE_COMMIT_AUDIT.getAuditStatus();
        List<MchntAcctInfo> mchntAcctInfoList = new ArrayList<>();
        List<BizTmp> bizTmpList = new ArrayList<>();
        List<BizHistory> bizHistoryList = new ArrayList<>();
        String modifyTime = DateUtil.getCurrentDateTime(BompAppParamConstant.yyyy_MM_dd_HHmmssSSS);

        /* 修改商户基本信息 */
        MchntBaseInfo modifyBaseInfo = new MchntBaseInfo();
        BeanUtil.beanCopy(mchntBaseInfo, modifyBaseInfo);


        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
        //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
        BizTmp bizTmp = bizTmpMapper.selectBizTmpByRealId(mchntBaseInfo.getInstId(), mchntBaseInfo.getId());
        if (null == bizTmp) {
            bizTmp = new BizTmp();
            ConvertUtil.convertOutput(bizTmp);
            bizTmp.setMchntName(mchntBaseInfo.getMchntName());
            bizTmp.setManageInstId(mchntBaseInfo.getSignInstId());
            bizTmp.setRealId(mchntBaseInfo.getId());
            bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_BASE_INFO);
            bizTmp.setDetailFlag(AppParamConstant.NO);
            bizTmp.setMasterShowFlag(AppParamConstant.YES);
        } else if (AuditStatusEnum.MODIFY_BE_COMMIT_AUDIT.getAuditStatus().equals(mchntBaseInfo.getAuditStatus())) {
            //若当前状态为修改待提交，则取临时表中的数据进行修改   (例如，在商户基本管理页面进行了修改，此时临时表中存的是修改后的数据，此时进行结算账户修改，修改结算模式，则需从临时表中取数据，进行修改再存放到临时表中)
            String tmpBaseInfoJson = InitParamUtil.getJsonString(bizTmp);
            MchntBaseInfo tmpBaseInfo = JSON.parseObject(tmpBaseInfoJson, MchntBaseInfo.class);
            BeanUtil.beanCopy(tmpBaseInfo, modifyBaseInfo);
        }

        modifyBaseInfo.setRealSettleFlag(request.getRealSettleFlag());
        modifyBaseInfo.setMchntSettleMode(request.getMchntSettleMode());
        if (!StringUtil.isEmptyOrNull(request.getCashWithdrawalFlag())) {
            modifyBaseInfo.setCashWithdrawalFlag(request.getCashWithdrawalFlag());
        }
        modifyBaseInfo.setAuditStatus(auditStatus);
        modifyBaseInfo.setLastOprId(request.getUserId());

        mchntBaseInfo.setAuditStatus(auditStatus);
        mchntBaseInfo.setLastAuditId(request.getUserId());
        mchntBaseInfo.setLastUpdateTime(modifyTime);

        //修改
        bizTmp.setBizOpr("U");
        bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
        //修改待提交审批
        bizTmp.setAuditStatus(auditStatus);
        String modifyMchntBaseInfoJson = JSONObject.toJSONString(modifyBaseInfo);
        InitParamUtil.initBizTempData(bizTmp, modifyMchntBaseInfoJson);
        bizTmpList.add(bizTmp);

        BizHistory bizHistory = new BizHistory();
        BeanUtil.beanCopy(bizTmp, bizHistory);
        bizHistory.setCreateTime(modifyTime);
        //将正式表的商户信息存入历史表 bizData
        String[] ignore = new String[]{"auditStatus", "lastOprId", "lastUpdateTime"};
        String compareModify = CompareFieldsUtil.compareFields(mchntBaseInfo, modifyBaseInfo, ignore);
        if (StringUtil.isEmptyOrNull(compareModify)) {
            compareModify = "没有修改该结算账户数据";
            rglog.debug("结算信息管理-修改商户签约信息，与数据库信息对比，没有修改数据。");
        }
        InitParamUtil.initBizHistoryData(bizHistory, compareModify);

        for (SettleAcctInfoBean settleAcctInfoBean : request.getSettleAcctInfoBeanList()) {
            //校验法人名称与结算账户名称是否一致，不一致则拒绝
            verifyMchntArtifNameAndSettleAcctName(mchntBaseInfo, mchntSignInfo, settleAcctInfoBean);

            if (!AppParamConstant.NO.equals(request.getRealSettleFlag())) {
                if (AppParamConstant.YES.equals(mchntBaseInfo.getRealSettleFlag())) {
                    rglog.debug("该商户<{}>已开通实时清算,不进行开通实时清算资格校验.", mchntBaseInfo.getMchntNo());
                } else {
                    //判断该法人行是否允许设置实时清算
                    SysParamMapper sysParamMapper = new SysParamMapperImpl();
                    SysParam sysParam = sysParamMapper.selectSysParamByPrimaryKey(mchntBaseInfo.getInstId(), BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.ALLOW_MCHNT_INNER_BANK_CARD_D0_INST);
                    if (null == sysParam || AppParamConstant.NO.equals(sysParam.getParamValue())) {
                        rglog.error("该法人行不允许设置D0与提现！inst:<{}>，mchntNo:<{}>", mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                        throw new BizException(RespCodeEnum.NOT_ALLOW_D0_BY_INST.getRespCode(), RespCodeEnum.NOT_ALLOW_D0_BY_INST.getRespDesc());
                    }

                    //校验是否满足监管要求
                    MchntVerifyService mchntVerifyService = new MchntVerifyServiceImpl();
                    if (!mchntVerifyService.verifyMchntAllowToD0(mchntBaseInfo)) {
                        rglog.error("该商户未达到提现要求，不允许设置提现费率！instId:{}, mchntNo:{}", mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                        throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
                    }
                }
            }

            if (BompSettleTypeEnum.STRING_SETTLE_TYPE_D0.equals(settleAcctInfoBean.getSettleType())) {
                //判断该法人行是否允许设置D0
                SysParamMapper sysParamMapper = new SysParamMapperImpl();
                SysParam sysParam = sysParamMapper.selectSysParamByPrimaryKey(mchntBaseInfo.getInstId(), BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.ALLOW_MCHNT_D0_SETTLE_INST);
                if (null == sysParam || AppParamConstant.NO.equals(sysParam.getParamValue())) {
                    rglog.error("该法人行不允许设置D0与提现！inst:<{}>，mchntNo:<{}>", mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                    throw new BizException(RespCodeEnum.NOT_ALLOW_D0_BY_INST.getRespCode(), RespCodeEnum.NOT_ALLOW_D0_BY_INST.getRespDesc());
                }

                boolean D0Flag = false;//是否已开通D0,如果已开通则不校验
                MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
                List<MchntAcctInfo> dbMchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByMchntNo(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                for (MchntAcctInfo mchntAcctInfo : dbMchntAcctInfoList) {
                    if (AppParamConstant.YES.equals(mchntAcctInfo.getRecordStatus()) && BompSettleTypeEnum.STRING_SETTLE_TYPE_D0.equals(mchntAcctInfo.getSettleType())) {
                        D0Flag = true;
                        rglog.debug("该商户<{}>已开通D0,不进行开通D0资格校验.", mchntBaseInfo.getMchntNo());
                    }
                }

                if (!D0Flag) {
                    //校验是否满足监管要求
                    MchntVerifyService mchntVerifyService = new MchntVerifyServiceImpl();
                    if (!mchntVerifyService.verifyMchntAllowToD0(mchntBaseInfo)) {
                        rglog.error("该商户未达到提现要求，不允许设置提现费率！instId:{}, mchntNo:{}", mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                        throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
                    }
                }

                if (AppParamConstant.YES.equals(request.getCashWithdrawalFlag())) {
                    //不允许开通提现
                    rglog.error("结算账户为D0结算，不允许开通提现");
                    throw new BizException(RespCodeEnum.NOT_TO_ALLOW_WITHDRAWAL_AND_DO.getRespCode(), RespCodeEnum.NOT_TO_ALLOW_WITHDRAWAL_AND_DO.getRespDesc());
                }
            }

            if (BompSettleTypeEnum.SETTLE_TYPE_D0.getType().equals(settleAcctInfoBean.getSettleType())
                    || BompSettleTypeEnum.SETTLE_TYPE_D1.getType().equals(settleAcctInfoBean.getSettleType())
                    || AppParamConstant.YES.equals(request.getRealSettleFlag())
                    || AppParamConstant.YES.equals(request.getCashWithdrawalFlag())) {
                /* 获取机构内部户 提现/D0（本行）： 垫资户  */
                SettleAcctTypeEnum settleAcctTypeEnum = SettleAcctTypeEnum.DZ_SUBJECT;
                RoleAcctInfoMapper roleAcctInfoMapper = new RoleAcctInfoMapperImpl();
                RoleAcctInfo roleAcctInfo = roleAcctInfoMapper.selectBompBankRoleAcctInfoBySettleAcctId(mchntBaseInfo.getInstId(), settleAcctTypeEnum.getSettleAcct());
                if (null == roleAcctInfo) {
                    rglog.error("查询法人行垫资户失败，不允许设置D0或D1！userId:<{}>，mchntNo:<{}>", request.getUserId(), mchntBaseInfo.getMchntNo());
                    throw new BizException(RespCodeEnum.NOT_ALLOW_D0_WITHDRAWAL.getRespCode(), RespCodeEnum.NOT_ALLOW_D0_WITHDRAWAL.getRespDesc());
                }

                /* 校验是否存在特殊费率商户，若存在特殊费率商户，则不允许设置D0,D1 */
                MchntFeeInfoMapper mchntFeeInfoMapper = new MchntFeeInfoMapperImpl();
                List<MchntFeeInfo> mchntFeeInfoList = mchntFeeInfoMapper.selectMchntFeeInfoByMchntNo(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                if (!CollectionUtils.isEmpty(mchntFeeInfoList)) {
                    for (MchntFeeInfo mchntFeeInfo : mchntFeeInfoList) {
                        if ("0".equals(mchntFeeInfo.getFeeInputMode())
                                && !StringUtil.isEmptyOrNull(mchntFeeInfo.getFeeCode())) {
                            //特殊费率，且在当前日期生效
                            if (DateUtil.compareDate(DateUtil.getCurrentDate(), mchntFeeInfo.getFeeEffectiveDate()) >= 0
                                    && DateUtil.compareDate(DateUtil.getCurrentDate(), mchntFeeInfo.getFeeExpiryDate()) <= 0) {
                                rglog.error("商户使用特殊费率不允许设置D0/D1，instId:{},mchntNo:{}。",
                                        mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                                throw new BizException(RespCodeEnum.NOT_ALLOW_TO_SET_WITHDRAWAL_OF_FEE.getRespCode(), RespCodeEnum.NOT_ALLOW_TO_SET_WITHDRAWAL_OF_FEE.getRespDesc());
                            }
                        }
                    }
                }

                List<BizTmp> feeBizList = bizTmpMapper.selectBizTmpByMchntNo(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo(), TableNameConstant.T_B_MCHNT_FEE_INFO);
                if (!CollectionUtils.isEmpty(feeBizList)) {
                    //若修改草稿中含有特殊费率商户，不允许设置D0,D1
                    feeBizList = feeBizList.stream().filter(item -> AuditStatusEnum.MODIFY_BE_COMMIT_AUDIT.getAuditStatus().equals(item.getAuditStatus())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(feeBizList)) {
                        List<MchntFeeInfo> feeInfoBizList = feeBizList.stream().map(item -> JSON.parseObject(InitParamUtil.getJsonString(item), MchntFeeInfo.class)).collect(Collectors.toList());
                        for (MchntFeeInfo mchntFeeInfo : feeInfoBizList) {
                            if ("0".equals(mchntFeeInfo.getFeeInputMode())
                                    && !StringUtil.isEmptyOrNull(mchntFeeInfo.getFeeCode())) {
                                //特殊费率，且在当前日期生效
                                if (DateUtil.compareDate(DateUtil.getCurrentDate(), mchntFeeInfo.getFeeEffectiveDate()) > 0
                                        && DateUtil.compareDate(DateUtil.getCurrentDate(), mchntFeeInfo.getFeeExpiryDate()) < 0) {
                                    rglog.error("商户使用特殊费率不允许设置D0/D1，instId:{}, mchntNo:{}。",
                                            mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                                    throw new BizException(RespCodeEnum.NOT_ALLOW_TO_SET_WITHDRAWAL_OF_FEE.getRespCode(), RespCodeEnum.NOT_ALLOW_TO_SET_WITHDRAWAL_OF_FEE.getRespDesc());
                                }
                            }
                        }
                    }
                }
            }

            /* 获取修改的结算信息列表 */
            getModifySettleInfoList(request, mchntBaseInfo, mchntAcctInfoList, bizTmpList, bizHistoryList, modifyTime, settleAcctInfoBean, auditStatus);
        }

        //从收支两线改为轧差清算
        if ("00".equals(request.getMchntSettleMode()) && "01".equals(mchntBaseInfo.getMchntSettleMode())) {
            MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
            MchntAcctInfo dbMchntAcctInfo = mchntAcctInfoMapper.selectMchntAcctInfoByPrimaryKey(request.getHeader().getInstId(),
                    request.getMchntNo(), "*", "01");
            if (null == dbMchntAcctInfo) {
                rglog.error("从收支两线改为轧差清算，查询手续费结算账户失败！");
                throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
            }

            //判断当前状态是否允许修改
            if (!ChangeNextStatusUtil.isAllowModifyData(dbMchntAcctInfo.getAuditStatus())) {
                rglog.error("修改商户结算信息失败, 当前商户结算信息待审核，不允许修改，instId:{},mchntNo:{},当前商户审核状态:{}",
                        dbMchntAcctInfo.getInstId(), dbMchntAcctInfo.getMchntNo(), dbMchntAcctInfo.getAuditStatus());
                throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
            }

            //原商户信息改为 修改待提交审批
            dbMchntAcctInfo.setAuditStatus(auditStatus);
            dbMchntAcctInfo.setLastOprId(request.getUserId());
            dbMchntAcctInfo.setLastUpdateTime(modifyTime);
            mchntAcctInfoList.add(dbMchntAcctInfo);

            //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
            BizTmp bizAcctTmp = bizTmpMapper.selectBizTmpByRealId(dbMchntAcctInfo.getInstId(), dbMchntAcctInfo.getId());
            if (null == bizAcctTmp) {
                bizAcctTmp = new BizTmp();
                ConvertUtil.convertOutput(bizAcctTmp);
                bizAcctTmp.setMchntName(mchntBaseInfo.getMchntName());
                bizAcctTmp.setManageInstId(mchntBaseInfo.getSignInstId());
                bizAcctTmp.setRealId(dbMchntAcctInfo.getId());
                bizAcctTmp.setDetailFlag(BompAppParamConstant.FLAG_Y);
                bizAcctTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_ACCT_INFO);
            }

            MchntAcctInfo modifyMchntAcctInfo = new MchntAcctInfo();
            BeanUtil.beanCopy(dbMchntAcctInfo, modifyMchntAcctInfo);
            //若当前状态为修改待提交，则取临时表中的数据进行修改   (例如，在商户基本管理页面进行了修改，此时临时表中存的是修改后的数据，此时进行结算账户修改，修改结算模式，则需从临时表中取数据，进行修改再存放到临时表中)
            if (AuditStatusEnum.MODIFY_BE_COMMIT_AUDIT.getAuditStatus().equals(dbMchntAcctInfo.getAuditStatus())) {
                String tmpAcctInfoJson = InitParamUtil.getJsonString(bizAcctTmp);
                MchntAcctInfo tmpAcctInfo = JSON.parseObject(tmpAcctInfoJson, MchntAcctInfo.class);
                BeanUtil.beanCopy(tmpAcctInfo, modifyMchntAcctInfo);
            }
            //将手续费账户状态变为 N
            modifyMchntAcctInfo.setRecordStatus(AppParamConstant.NO);
            bizAcctTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
            //修改
            bizAcctTmp.setBizOpr("U");
            //修改待提交审批
            bizAcctTmp.setAuditStatus(auditStatus);
            String modifyMchntAcctInfoJson = JSONObject.toJSONString(modifyMchntAcctInfo);
            InitParamUtil.initBizTempData(bizAcctTmp, modifyMchntAcctInfoJson);
            bizTmpList.add(bizAcctTmp);

        }


        MchntFeeInfo mchntFeeInfo = null;
        if (BompAppParamConstant.FLAG_Y.equals(request.getCashWithdrawalFlag())
                && null != request.getCashWithdrawalFeeInfoBean()
                && !StringUtil.isEmptyOrNull(request.getCashWithdrawalFeeInfoBean().getFeeCode())) {

            CashWithdrawalFeeInfoBean cashWithdrawalFeeInfoBean = request.getCashWithdrawalFeeInfoBean();
            MchntFeeInfoMapper mchntFeeInfoMapper = new MchntFeeInfoMapperImpl();
            String date = DateUtil.getCurrentDate();
            MchntFeeInfo dbMchntFeeInfo = mchntFeeInfoMapper.selectMchntFeeInfoByCondition(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo(), cashWithdrawalFeeInfoBean.getBaseProdCode(), cashWithdrawalFeeInfoBean.getFeeType(), date);
            if (null == dbMchntFeeInfo) {
                rglog.error("未进行提现费率设置，不允许进行修改！");
                throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
            }

            dbMchntFeeInfo.setAuditStatus(auditStatus);
            dbMchntFeeInfo.setLastUpdateTime(modifyTime);
            dbMchntFeeInfo.setLastOprId(request.getUserId());
            mchntFeeInfo = new MchntFeeInfo();
            BeanUtil.beanCopy(dbMchntFeeInfo, mchntFeeInfo);

            BizTmp oldFeeTmp = bizTmpMapper.selectBizTmpByRealId(dbMchntFeeInfo.getInstId(), dbMchntFeeInfo.getId());
            //新费率生效日期的前一天
            dbMchntFeeInfo.setFeeExpiryDate(DateUtil.getBaseDateOffsetDay(cashWithdrawalFeeInfoBean.getFeeEffectiveDate(), -1));
            oldFeeTmp.setAuditStatus(auditStatus);
            oldFeeTmp.setLastOprId(dbMchntFeeInfo.getLastOprId());
            oldFeeTmp.setLastUpdateTime(dbMchntFeeInfo.getLastUpdateTime());
            InitParamUtil.initBizTempData(oldFeeTmp, JSONObject.toJSONString(dbMchntFeeInfo));
            bizTmpList.add(oldFeeTmp);

            MchntFeeInfo newFeeInfo = InitParamUtil.initMchntFeeInfoByCastWithdraw(cashWithdrawalFeeInfoBean, mchntBaseInfo, auditStatus, modifyTime, request.getUserId());
            BizTmp newFeeBizTmp = InitParamUtil.initBizTmpByCreate(mchntBaseInfo, newFeeInfo.getId(),
                    JSONObject.toJSONString(newFeeInfo), TableNameConstant.T_B_MCHNT_FEE_INFO, auditStatus,
                    BompAppParamConstant.FLAG_N, BompAppParamConstant.FLAG_N);
            bizTmpList.add(newFeeBizTmp);
        }


        //需要审核， 更新正式表的信息为修改待审核， 将传入的商户信息更新到业务临时表
        modifyMchntAcctInfoDb(request, xmlTreeUtil, mchntBaseInfo, mchntAcctInfoList, mchntFeeInfo, bizTmpList, null);

    }


    private void getModifySettleInfoByCreateHandle(MchntSettleInfoManageRequest request, MchntBaseInfo mchntBaseInfo,
                                                   List<MchntAcctInfo> mchntAcctInfoList, List<BizTmp> bizTmpList, String modifyTime,
                                                   SettleAcctInfoBean settleAcctInfoBean) throws Exception {
        String auditStatus = mchntBaseInfo.getAuditStatus();
        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();

        MchntAcctInfo dbMchntAcctInfo = mchntAcctInfoMapper.selectMchntAcctInfoByPrimaryKey(request.getHeader().getInstId(),
                request.getMchntNo(), settleAcctInfoBean.getBaseProdCode(), settleAcctInfoBean.getFundType());
        if (null == dbMchntAcctInfo) {
            rglog.info("修改商户结算信息失败, 根据商户号查询商户结算信息为空，instId:{},mchntNo:{},baseProdCode:{},fundType:{}.",
                    request.getHeader().getInstId(), request.getMchntNo(), settleAcctInfoBean.getBaseProdCode(), settleAcctInfoBean.getFundType());
            rglog.info("则为新增商户结算信息。");
            MchntAcctInfo mchntAcctInfo = new MchntAcctInfo();
            BeanUtil.beanCopy(settleAcctInfoBean, mchntAcctInfo);
            String id = RandomUtil.getUUID();
            mchntAcctInfo.setId(id);
            mchntAcctInfo.setMchntNo(mchntBaseInfo.getMchntNo());
            mchntAcctInfo.setInstId(mchntBaseInfo.getInstId());
            mchntAcctInfo.setAcctOpenBankNo(settleAcctInfoBean.getSettleAcctBankNo());
            mchntAcctInfo.setAcctOpenBankName(settleAcctInfoBean.getSettleAcctBankName());
            mchntAcctInfo.setAcctOpenProvince(settleAcctInfoBean.getSettleAcctBankProvince());
            mchntAcctInfo.setAcctOpenCity(settleAcctInfoBean.getSettleAcctBankCity());
            mchntAcctInfo.setAcctOpenArea(settleAcctInfoBean.getSettleAcctBankArea());
            mchntAcctInfo.setOprId(request.getUserId());
            mchntAcctInfo.setAuditStatus(auditStatus);
            mchntAcctInfo.setRecordStatus(BompAppParamConstant.FLAG_Y);
            mchntAcctInfo.setAcctSignFlag(BompAppParamConstant.FLAG_N);
            mchntAcctInfo.setCreateTime(modifyTime);
            dbMchntAcctInfo = mchntAcctInfo;
        }

        //判断当前状态是否允许修改
        if (!ChangeNextStatusUtil.isAllowModifyData(dbMchntAcctInfo.getAuditStatus())) {
            rglog.error("修改商户结算信息失败, 当前商户结算信息待审核，不允许修改，instId:{},mchntNo:{},当前商户审核状态:{}",
                    dbMchntAcctInfo.getInstId(), dbMchntAcctInfo.getMchntNo(), dbMchntAcctInfo.getAuditStatus());
            throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
        }
        dbMchntAcctInfo.setAuditStatus(auditStatus);
        dbMchntAcctInfo.setLastOprId(request.getUserId());
        dbMchntAcctInfo.setLastUpdateTime(modifyTime);

        //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查; 新增数据）
        BizTmp bizTmp = bizTmpMapper.selectBizTmpByRealId(dbMchntAcctInfo.getInstId(), dbMchntAcctInfo.getId());
        if (null == bizTmp) {
            bizTmp = new BizTmp();
            ConvertUtil.convertOutput(bizTmp);
            bizTmp.setMchntName(mchntBaseInfo.getMchntName());
            bizTmp.setManageInstId(mchntBaseInfo.getSignInstId());
            bizTmp.setRealId(dbMchntAcctInfo.getId());
            bizTmp.setDetailFlag(BompAppParamConstant.FLAG_Y);
            bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_ACCT_INFO);
            bizTmp.setMasterKey(mchntBaseInfo.getId());
            bizTmp.setMasterShowFlag(BompAppParamConstant.FLAG_N);
        }


        BeanUtil.beanCopy(settleAcctInfoBean, dbMchntAcctInfo);
        dbMchntAcctInfo.setAcctOpenBankNo(settleAcctInfoBean.getSettleAcctBankNo());
        dbMchntAcctInfo.setAcctOpenBankName(settleAcctInfoBean.getSettleAcctBankName());
        dbMchntAcctInfo.setAcctOpenProvince(settleAcctInfoBean.getSettleAcctBankProvince());
        dbMchntAcctInfo.setAcctOpenCity(settleAcctInfoBean.getSettleAcctBankCity());
        dbMchntAcctInfo.setAcctOpenArea(settleAcctInfoBean.getSettleAcctBankArea());
        String[] ignore = new String[]{"auditStatus", "lastOprId", "lastUpdateTime"};
        String compareModify = CompareFieldsUtil.compareFields(dbMchntAcctInfo, dbMchntAcctInfo, ignore);
        if (StringUtil.isEmptyOrNull(compareModify)) {
            compareModify = "没有修改该结算账户数据";
            rglog.debug("结算账户信息管理-修改商户签约信息，与数据库信息对比，没有修改数据。");
        }

        bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
        //修改
        bizTmp.setBizOpr("U");
        //修改待提交审批
        bizTmp.setAuditStatus(auditStatus);
        String modifyMchntAcctInfoJson = JSONObject.toJSONString(dbMchntAcctInfo);
        InitParamUtil.initBizTempData(bizTmp, modifyMchntAcctInfoJson);
        bizTmpList.add(bizTmp);

        //新增失败或新增草稿状态，直接更新正式表
        mchntAcctInfoList.add(dbMchntAcctInfo);
    }

    private void getModifySettleInfoList(MchntSettleInfoManageRequest request, MchntBaseInfo mchntBaseInfo,
                                         List<MchntAcctInfo> mchntAcctInfoList, List<BizTmp> bizTmpList,
                                         List<BizHistory> bizHistoryList, String modifyTime,
                                         SettleAcctInfoBean settleAcctInfoBean, String auditStatus) throws Exception {
        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();

        MchntAcctInfo dbMchntAcctInfo = mchntAcctInfoMapper.selectMchntAcctInfoByPrimaryKey(request.getHeader().getInstId(),
                request.getMchntNo(), settleAcctInfoBean.getBaseProdCode(), settleAcctInfoBean.getFundType());
        if (null == dbMchntAcctInfo) {
            rglog.info("修改商户结算信息失败, 根据商户号查询商户结算信息为空，instId:{},mchntNo:{},baseProdCode:{},fundType:{}.",
                    request.getHeader().getInstId(), request.getMchntNo(), settleAcctInfoBean.getBaseProdCode(), settleAcctInfoBean.getFundType());
            rglog.info("则为新增商户结算信息。");
            initModifyToAddAcctInfo(request, mchntBaseInfo, bizTmpList, modifyTime, settleAcctInfoBean, auditStatus, "U");
        } else {
            //判断当前状态是否允许修改
            if (!ChangeNextStatusUtil.isAllowModifyData(dbMchntAcctInfo.getAuditStatus())) {
                rglog.error("修改商户结算信息失败, 当前商户结算信息待审核，不允许修改，instId:{},mchntNo:{},当前商户审核状态:{}",
                        dbMchntAcctInfo.getInstId(), dbMchntAcctInfo.getMchntNo(), dbMchntAcctInfo.getAuditStatus());
                throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
            }

            //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
            BizTmp bizTmp = bizTmpMapper.selectBizTmpByRealId(dbMchntAcctInfo.getInstId(), dbMchntAcctInfo.getId());
            if (null == bizTmp) {
                bizTmp = new BizTmp();
                ConvertUtil.convertOutput(bizTmp);
                bizTmp.setMchntName(mchntBaseInfo.getMchntName());
                bizTmp.setManageInstId(mchntBaseInfo.getSignInstId());
                bizTmp.setRealId(dbMchntAcctInfo.getId());
                bizTmp.setDetailFlag(BompAppParamConstant.FLAG_Y);
                bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_ACCT_INFO);
            }

            MchntAcctInfo modifyMchntAcctInfo = new MchntAcctInfo();
            BeanUtil.beanCopy(dbMchntAcctInfo, modifyMchntAcctInfo);
            //若当前状态为修改待提交，则取临时表中的数据进行修改   (例如，在商户基本管理页面进行了修改，此时临时表中存的是修改后的数据，此时进行结算账户修改，修改结算模式，则需从临时表中取数据，进行修改再存放到临时表中)
            if (AuditStatusEnum.MODIFY_BE_COMMIT_AUDIT.getAuditStatus().equals(dbMchntAcctInfo.getAuditStatus())) {
                String tmpAcctInfoJson = InitParamUtil.getJsonString(bizTmp);
                MchntAcctInfo tmpAcctInfo = JSON.parseObject(tmpAcctInfoJson, MchntAcctInfo.class);
                BeanUtil.beanCopy(tmpAcctInfo, modifyMchntAcctInfo);
            }

            //原商户信息改为 修改待提交审批
            dbMchntAcctInfo.setAuditStatus(auditStatus);
            dbMchntAcctInfo.setLastOprId(request.getUserId());
            dbMchntAcctInfo.setLastUpdateTime(modifyTime);
            modifyMchntAcctInfo.setAuditStatus(auditStatus);
            modifyMchntAcctInfo.setLastOprId(request.getUserId());
            modifyMchntAcctInfo.setLastUpdateTime(modifyTime);

            BeanUtil.beanCopy(settleAcctInfoBean, modifyMchntAcctInfo);
            modifyMchntAcctInfo.setRecordStatus(AppParamConstant.YES);
            modifyMchntAcctInfo.setAcctOpenBankNo(settleAcctInfoBean.getSettleAcctBankNo());
            modifyMchntAcctInfo.setAcctOpenBankName(settleAcctInfoBean.getSettleAcctBankName());
            modifyMchntAcctInfo.setAcctOpenProvince(settleAcctInfoBean.getSettleAcctBankProvince());
            modifyMchntAcctInfo.setAcctOpenCity(settleAcctInfoBean.getSettleAcctBankCity());
            modifyMchntAcctInfo.setAcctOpenArea(settleAcctInfoBean.getSettleAcctBankArea());
            if (!dbMchntAcctInfo.getSettleAcctNo().equals(settleAcctInfoBean.getSettleAcctNo())) {
                //如果结算账户不一致，则
                modifyMchntAcctInfo.setAcctSignFlag(AppParamConstant.NO);
            }

            String[] ignore = new String[]{"auditStatus", "lastOprId", "lastUpdateTime"};
            String compareModify = CompareFieldsUtil.compareFields(dbMchntAcctInfo, modifyMchntAcctInfo, ignore);
            if (StringUtil.isEmptyOrNull(compareModify)) {
                compareModify = "没有修改该结算账户数据";
                rglog.debug("结算账户信息管理-修改商户签约信息，与数据库信息对比，没有修改数据。");
            }

            bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
            //修改
            bizTmp.setBizOpr("U");
            //修改待提交审批
            bizTmp.setAuditStatus(auditStatus);
            String modifyMchntAcctInfoJson = JSONObject.toJSONString(modifyMchntAcctInfo);
            InitParamUtil.initBizTempData(bizTmp, modifyMchntAcctInfoJson);
            bizTmpList.add(bizTmp);

            BizHistory bizHistory = new BizHistory();
            BeanUtil.beanCopy(bizTmp, bizHistory);
            bizHistory.setCreateTime(modifyTime);
            //将正式表的商户信息存入历史表 bizData
            InitParamUtil.initBizHistoryData(bizHistory, compareModify);
            mchntAcctInfoList.add(dbMchntAcctInfo);

            bizHistoryList.add(bizHistory);
        }

    }

    private void initModifyToAddAcctInfo(MchntSettleInfoManageRequest request, MchntBaseInfo mchntBaseInfo, List<BizTmp> bizTmpList, String modifyTime, SettleAcctInfoBean settleAcctInfoBean, String auditStatus, String bizOpr) throws Exception {
        MchntAcctInfo mchntAcctInfo = new MchntAcctInfo();
        BeanUtil.beanCopy(settleAcctInfoBean, mchntAcctInfo);
        String id = RandomUtil.getUUID();
        mchntAcctInfo.setId(id);
        mchntAcctInfo.setMchntNo(mchntBaseInfo.getMchntNo());
        mchntAcctInfo.setInstId(mchntBaseInfo.getInstId());
        mchntAcctInfo.setAcctOpenBankNo(settleAcctInfoBean.getSettleAcctBankNo());
        mchntAcctInfo.setAcctOpenBankName(settleAcctInfoBean.getSettleAcctBankName());
        mchntAcctInfo.setAcctOpenProvince(settleAcctInfoBean.getSettleAcctBankProvince());
        mchntAcctInfo.setAcctOpenCity(settleAcctInfoBean.getSettleAcctBankCity());
        mchntAcctInfo.setAcctOpenArea(settleAcctInfoBean.getSettleAcctBankArea());
        mchntAcctInfo.setOprId(request.getUserId());
        mchntAcctInfo.setAuditStatus(auditStatus);
        mchntAcctInfo.setRecordStatus(BompAppParamConstant.FLAG_Y);
        mchntAcctInfo.setAcctSignFlag(BompAppParamConstant.FLAG_N);
        mchntAcctInfo.setCreateTime(modifyTime);

        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
        List<BizTmp> mchntAcctInfoBizTmpList = bizTmpMapper.selectBizTmpByMchntNo(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo(), TableNameConstant.T_B_MCHNT_ACCT_INFO);
        if (!CollectionUtils.isEmpty(mchntAcctInfoBizTmpList) && mchntAcctInfoBizTmpList.size() >= 2) {
            //原来临时表有数据，未更新到正式表，则直接修改临时表中的数据
            for (BizTmp mchntAcctInfoBizTmp : mchntAcctInfoBizTmpList) {
                String mchntAcctJson = InitParamUtil.getJsonString(mchntAcctInfoBizTmp);
                MchntAcctInfo bizMchntAcctInfo = JSON.parseObject(mchntAcctJson, MchntAcctInfo.class);
                if (bizMchntAcctInfo.getFundType().equals(mchntAcctInfo.getFundType())) {
                    mchntAcctInfo.setId(bizMchntAcctInfo.getId());
                    BeanUtil.beanCopy(mchntAcctInfo, mchntAcctInfoBizTmp);
                    String mchntAcctInfoJson = JSONObject.toJSONString(mchntAcctInfo);
                    InitParamUtil.initBizTempData(mchntAcctInfoBizTmp, mchntAcctInfoJson);
                    bizTmpList.add(mchntAcctInfoBizTmp);
                    return;
                }
            }

        } else {
            BizTmp bizTmp = new BizTmp();
            ConvertUtil.convertOutput(bizTmp);
            BeanUtil.beanCopy(mchntAcctInfo, bizTmp);
            bizTmp.setManageInstId(mchntBaseInfo.getSignInstId());
            bizTmp.setMchntName(mchntBaseInfo.getMchntName());
            bizTmp.setRealId(id);
            bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_ACCT_INFO);
            bizTmp.setBizOpr(bizOpr);
            bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
            bizTmp.setAuditStatus(auditStatus);
            bizTmp.setMasterKey(mchntBaseInfo.getId());
            bizTmp.setDetailFlag(BompAppParamConstant.FLAG_Y);
            String mchntAcctInfoJson = JSONObject.toJSONString(mchntAcctInfo);
            InitParamUtil.initBizTempData(bizTmp, mchntAcctInfoJson);
            bizTmpList.add(bizTmp);
        }

    }

    private void modifyMchntAcctInfoDb(MchntSettleInfoManageRequest request,
                                       XmlTreeUtil xmlTreeUtil,
                                       MchntBaseInfo mchntBaseInfo,
                                       List<MchntAcctInfo> mchntAcctInfoList,
                                       MchntFeeInfo mchntFeeInfo,
                                       List<BizTmp> bizTmpList,
                                       List<BizHistory> bizHistoryList) throws Exception {
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.MCMP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.MCMP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
        try {

            int dbResult;

            //更新商户结算状态等
            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            dbResult = mchntBaseInfoMapper.updateMchntBaseInfoById(mchntBaseInfo);
            if (dbResult != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("新增商户结算信息：更新商户基本信息表失败！id:{},mchnt:{},instId:{}",
                        mchntBaseInfo.getId(), mchntBaseInfo.getMchntNo(), mchntBaseInfo.getInstId());
                throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
            }


            for (MchntAcctInfo mchntAcctInfo : mchntAcctInfoList) {
                dbResult = mchntAcctInfoMapper.insertMchntAcctInfo(mchntAcctInfo);
                if (dbResult != 0) {
                    dbResult = mchntAcctInfoMapper.updateMchntAcctInfoById(mchntAcctInfo);
                    if (dbResult != 0) {
                        dbsUtil.dbsEndTransaction(false);
                        rglog.error("修改商户结算信息表失败！id:{},mchnt:{},instId:{}",
                                mchntAcctInfo.getId(), mchntAcctInfo.getMchntNo(), mchntAcctInfo.getInstId());
                        throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                    }
                }
            }

            if (null != mchntFeeInfo) {
                MchntFeeInfoMapper mchntFeeInfoMapper = new MchntFeeInfoMapperImpl();
                dbResult = mchntFeeInfoMapper.updateMchntFeeInfoById(mchntFeeInfo);
                if (dbResult != 0) {
                    dbsUtil.dbsEndTransaction(false);
                    rglog.error("修改商户费率信息表失败！mchntNo:{},ProdCode:{},BaseProdCode:{},FeeType:{}", mchntFeeInfo.getMchntNo(),
                            mchntFeeInfo.getProdCode(), mchntFeeInfo.getBaseProdCode(), mchntFeeInfo.getFeeType());
                    throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                }

            }

            if (!CollectionUtils.isEmpty(bizTmpList)) {
                BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();

                for (BizTmp bizTmp : bizTmpList) {
                    //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
                    BizTmp oldBizTemp = bizTmpMapper.selectBizTmpByRealId(bizTmp.getInstId(), bizTmp.getRealId());
                    if (null == oldBizTemp) {
                        dbResult = bizTmpMapper.insertBizTmp(bizTmp);
                    } else {
                        dbResult = bizTmpMapper.updateBizTmpByRealId(bizTmp);
                    }

                    if (dbResult != 0) {
                        dbsUtil.dbsEndTransaction(false);
                        rglog.error("修改商户结算信息-临时表记录失败！realId:{},manageInstId:{},instId:{}",
                                bizTmp.getRealId(), bizTmp.getManageInstId(), bizTmp.getInstId());
                        throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                    }
                }
            }

            if (!CollectionUtils.isEmpty(bizHistoryList)) {
                BizHistoryMapper bizHistoryMapper = new BizHistoryMapperImpl();

                for (BizHistory bizHistory : bizHistoryList) {
                    dbResult = bizHistoryMapper.insertBompBizHistory(bizHistory);
                    if (dbResult != 0) {
                        dbsUtil.dbsEndTransaction(false);
                        rglog.error("修改商户结算信息- 新增业务历史表记录失败！realId:{},manageInstId:{},instId:{}",
                                bizHistory.getRealId(), bizHistory.getManageInstId(), bizHistory.getInstId());
                        throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                    }
                }
            }

            //处理商户影像
            manageSettleImageInfo(request);

            dbsUtil.dbsEndTransaction(true);
        } catch (Exception e) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("商户结算管理失败！mchntNo:{}", mchntBaseInfo.getMchntNo());
            throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
        }
    }


    private void increaseMchntSettleInfo(MchntSettleInfoManageRequest request,
                                         XmlTreeUtil xmlTreeUtil,
                                         MchntBaseInfo dbMchntBaseInfo, MchntSignInfo mchntSignInfo) throws Exception {
        //参数校验
        MchntBaseInfo modifyBaseInfo = new MchntBaseInfo();
        List<MchntAcctInfo> dbMchntAcctInfoList = new ArrayList<>();
        List<BizTmp> bizTmpList = new ArrayList<>();
        List<BizHistory> bizHistoryList = new ArrayList<>();
        String time = DateUtil.getCurrentDateTime(BompAppParamConstant.yyyy_MM_dd_HHmmssSSS);

        //只修改事实清算标识，商户清算模式，是否开通提现
        BeanUtil.beanCopy(dbMchntBaseInfo, modifyBaseInfo);
        modifyBaseInfo.setRealSettleFlag(request.getRealSettleFlag());
        modifyBaseInfo.setMchntSettleMode(request.getMchntSettleMode());
        //是否开通提现，新增时默认不开通，按设置的结算周期进行结算
        modifyBaseInfo.setCashWithdrawalFlag(request.getCashWithdrawalFlag());
        modifyBaseInfo.setAuditStatus(AuditStatusEnum.BE_AUDIT.getAuditStatus());
        modifyBaseInfo.setLastUpdateTime(time);
        modifyBaseInfo.setLastOprId(request.getUserId());
        //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
        BizTmp bizTmp = bizTmpMapper.selectBizTmpByRealId(dbMchntBaseInfo.getInstId(), dbMchntBaseInfo.getId());
        if (null == bizTmp) {
            bizTmp = new BizTmp();
            BeanUtil.beanCopy(dbMchntBaseInfo, bizTmp);
            bizTmp.setMchntName(modifyBaseInfo.getMchntName());
            bizTmp.setManageInstId(modifyBaseInfo.getSignInstId());
            bizTmp.setRealId(modifyBaseInfo.getId());
            bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_BASE_INFO);
            bizTmp.setDetailFlag(BompAppParamConstant.FLAG_N);
            bizTmp.setMasterKey(dbMchntBaseInfo.getId());
        }

        bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
        //修改
        bizTmp.setBizOpr("I");
        String modifyMchntBaseInfoJson = JSONObject.toJSONString(modifyBaseInfo);
        InitParamUtil.initBizTempData(bizTmp, modifyMchntBaseInfoJson);
        bizTmpList.add(bizTmp);

        BizHistory bizHistory = new BizHistory();
        BeanUtil.beanCopy(bizTmp, bizHistory);
        bizHistory.setCreateTime(time);
        bizHistory.setBizChangeData1("新增商户基础信息-结算信息页面修改部分基础信息");


        if (!CollectionUtils.isEmpty(request.getSettleAcctInfoBeanList())) {
            for (SettleAcctInfoBean settleAcctInfoBean : request.getSettleAcctInfoBeanList()) {
                //校验企业注册类型，企业类型如果是个体需要校验商户法人跟商户结算账户户名是否一致
                verifyMchntArtifNameAndSettleAcctName(dbMchntBaseInfo, mchntSignInfo, settleAcctInfoBean);

                //新增若是 结算方式为D0 直接拒绝
                if (BompSettleTypeEnum.STRING_SETTLE_TYPE_D0.equals(settleAcctInfoBean.getSettleType())
                        || !BompAppParamConstant.FLAG_N.equals(request.getRealSettleFlag())
                        || !BompAppParamConstant.FLAG_N.equals(request.getCashWithdrawalFlag())) {
                    rglog.error("新增商户结算信息失败, 新增时结算方式不允许为D0,提现标识只能为N，instId:{},mchntNo:{}", request.getHeader().getInstId(), request.getMchntNo());
                    throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
                }

                if (BompSettleTypeEnum.SETTLE_TYPE_D1.getType().equals(settleAcctInfoBean.getSettleType())) {
                    /* 获取机构内部户 提现/D0（本行）： 垫资户  */
                    SettleAcctTypeEnum settleAcctTypeEnum = SettleAcctTypeEnum.DZ_SUBJECT;
                    RoleAcctInfoMapper roleAcctInfoMapper = new RoleAcctInfoMapperImpl();
                    RoleAcctInfo roleAcctInfo = roleAcctInfoMapper.selectBompBankRoleAcctInfoBySettleAcctId(dbMchntBaseInfo.getInstId(), settleAcctTypeEnum.getSettleAcct());
                    if (null == roleAcctInfo) {
                        rglog.error("查询法人行垫资户失败，不允许设置D0或D1！userId:<{}>，mchntNo:<{}>", request.getUserId(), dbMchntBaseInfo.getMchntNo());
                        throw new BizException(RespCodeEnum.NOT_ALLOW_D0_WITHDRAWAL.getRespCode(), RespCodeEnum.NOT_ALLOW_D0_WITHDRAWAL.getRespDesc());
                    }
                }

                //初始化结算账户信息
                initAcctInfoByCreate(request, dbMchntBaseInfo, dbMchntAcctInfoList, bizTmpList, bizHistoryList, settleAcctInfoBean, time);
            }

            createMchntAcctInfoDb(request, xmlTreeUtil, modifyBaseInfo, dbMchntAcctInfoList, bizTmpList, null);
        } else {
            rglog.error("未上送结算账户信息！，instId:{},mchntNo:{}", request.getHeader().getInstId(), request.getMchntNo());
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }


    }

    private void initAcctInfoByCreate(MchntSettleInfoManageRequest request,
                                      MchntBaseInfo mchntBaseInfo,
                                      List<MchntAcctInfo> dbMchntAcctInfoList,
                                      List<BizTmp> bizTmpList,
                                      List<BizHistory> bizHistoryList,
                                      SettleAcctInfoBean settleAcctInfoBean,
                                      String time) throws Exception {

        MchntAcctInfo mchntAcctInfo = InitParamUtil.initMchntAcctInfoByCreate(mchntBaseInfo, request.getUserId(), settleAcctInfoBean, time, mchntBaseInfo.getAuditStatus());
        dbMchntAcctInfoList.add(mchntAcctInfo);

        BizTmp bizTmp = new BizTmp();
        ConvertUtil.convertOutput(bizTmp);
        BeanUtil.beanCopy(mchntAcctInfo, bizTmp);
        bizTmp.setManageInstId(mchntBaseInfo.getSignInstId());
        bizTmp.setMchntName(mchntBaseInfo.getMchntName());
        bizTmp.setRealId(mchntAcctInfo.getId());
        bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_ACCT_INFO);
        //新增
        bizTmp.setBizOpr("I");
        bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
        bizTmp.setAuditStatus(AuditStatusEnum.BE_AUDIT.getAuditStatus());
        bizTmp.setMasterKey(mchntBaseInfo.getId());
        //是明细
        bizTmp.setDetailFlag(BompAppParamConstant.FLAG_Y);
        String mchntAcctInfoJson = JSONObject.toJSONString(mchntAcctInfo);
        InitParamUtil.initBizTempData(bizTmp, mchntAcctInfoJson);
        bizTmpList.add(bizTmp);

        BizHistory bizHistory = new BizHistory();
        BeanUtil.beanCopy(bizTmp, bizHistory);
        bizHistory.setBizChangeData1("新增映像信息");
        bizHistoryList.add(bizHistory);
    }

    /**
     * 新增商户结算信息
     */
    private void createMchntAcctInfoDb(MchntSettleInfoManageRequest request,
                                       XmlTreeUtil xmlTreeUtil,
                                       MchntBaseInfo mchntBaseInfo,
                                       List<MchntAcctInfo> dbMchntAcctInfoList,
                                       List<BizTmp> bizTmpList,
                                       List<BizHistory> bizHistoryList) throws Exception {
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.MCMP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.MCMP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();

        try {
            //更新商户结算模式、商户延迟清算标识，是否开通提现标识等
            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            int dbResult = mchntBaseInfoMapper.updateMchntBaseInfoById(mchntBaseInfo);
            if (dbResult != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("新增商户结算信息：更新商户基本信息表失败！id:{},mchnt:{},instId:{}",
                        mchntBaseInfo.getId(), mchntBaseInfo.getMchntNo(), mchntBaseInfo.getInstId());
                throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
            }


            MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
            for (MchntAcctInfo mchntAcctInfo : dbMchntAcctInfoList) {
                dbResult = mchntAcctInfoMapper.insertMchntAcctInfo(mchntAcctInfo);
                if (dbResult != 0) {
                    dbsUtil.dbsEndTransaction(false);
                    rglog.error("新增商户结算信息表失败！id:{},mchnt:{},instId:{}",
                            mchntAcctInfo.getId(), mchntAcctInfo.getMchntNo(), mchntAcctInfo.getInstId());
                    throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                }
            }

            if (!CollectionUtils.isEmpty(bizTmpList)) {
                BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
                for (BizTmp bizTmp : bizTmpList) {
                    dbResult = bizTmpMapper.insertBizTmp(bizTmp);
                    if (dbResult != 0) {
                        dbResult = bizTmpMapper.updateBizTmpByRealId(bizTmp);
                        if (dbResult != 0) {
                            dbsUtil.dbsEndTransaction(false);
                            rglog.error("新增商户结算信息-业务临时表记录失败！realId:{},manageInstId:{},instId:{}",
                                    bizTmp.getRealId(), bizTmp.getManageInstId(), bizTmp.getInstId());
                            throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                        }

                    }

                }
            }

            if (!CollectionUtils.isEmpty(bizHistoryList)) {
                BizHistoryMapper bizHistoryMapper = new BizHistoryMapperImpl();
                for (BizHistory bizHistory : bizHistoryList) {
                    dbResult = bizHistoryMapper.insertBompBizHistory(bizHistory);
                    if (dbResult != 0) {
                        dbsUtil.dbsEndTransaction(false);
                        rglog.error("新增商户结算信息-业务历史表记录失败！realId:{},manageInstId:{},instId:{}",
                                bizHistory.getRealId(), bizHistory.getManageInstId(), bizHistory.getInstId());
                        throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                    }
                }
            }

            //处理商户影像
            manageSettleImageInfo(request);

            dbsUtil.dbsEndTransaction(true);
        } catch (Exception e) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("商户结算管理失败！mchntNo:{}", mchntBaseInfo.getMchntNo());
            throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
        }
    }


    private void verifyMchntArtifNameAndSettleAcctName(MchntBaseInfo mchntBaseInfo,
                                                       MchntSignInfo mchntSignInfo,
                                                       SettleAcctInfoBean settleAcctInfoBean) throws Exception {
        rglog.debug("校验结算账户名称是否合法,settleAcctName:{},mchntName:{},legalName：{}",
                settleAcctInfoBean.getSettleAcctName(), mchntBaseInfo.getMchntName(), mchntSignInfo.getArtifName());

        if (BompMchntNatureEnum.ENTERPRISE.getMchntNature().equals(mchntBaseInfo.getMchntNature())) {
            rglog.debug("商户性质为企业，结算账户需为对公户/本行内部户");
            //商户类型为企业，必须为对公户/内部户
            if (cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.SELF_PUBLIC.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())
                    || cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.OTHER_PUBLIC.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())
                    || cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.SELF_INTERNAL.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())) {
                rglog.debug("结算账户为对公户/内部户，判断结算账户是否符合规则");
                if (mchntBaseInfo.getMchntName().equals(settleAcctInfoBean.getSettleAcctName())) {
                    rglog.debug("对公户且结算账户名称为商户名称，符合要求");
                    return;
                }
            } else {
                rglog.error("管理商户结算信息失败, 商户性质为企业，结算账户需为对公户，instId:{},mchntNo:{}", mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                throw new BizException(RespCodeEnum.VERIFY_ACCT_NAME_MATCH.getRespCode(), RespCodeEnum.VERIFY_ACCT_NAME_MATCH.getRespDesc());
            }
        } else {
            rglog.debug("商户性质为非企业，根据结算账户类型判断");
            if (cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.SELF_PUBLIC.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())
                    || cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.OTHER_PUBLIC.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())
                    || cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.SELF_INTERNAL.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())) {
                rglog.debug("结算账户为对公户/内部户，判断结算账户是否符合规则");
                if (mchntBaseInfo.getMchntName().equals(settleAcctInfoBean.getSettleAcctName())) {
                    rglog.debug("对公户且结算账户名称为商户名称，符合要求");
                    return;
                }
            } else if (mchntSignInfo.getArtifName().equals(settleAcctInfoBean.getSettleAcctName())) {
                rglog.debug("非对公户，结算账户户名为法人姓名，符合要求");
                return;
            }
        }


        //非本行内部户-不一致查看资金管理关系证明照是否上传，未上传返回失败
        if (!cc.rengu.igas.bomp.common.enums.SettleAcctTypeEnum.SELF_INTERNAL.getAcctType().equals(settleAcctInfoBean.getSettleAcctType())) {
            //校验是否上送资金存管证明
            if (!CollectionUtils.isEmpty(settleAcctInfoBean.getSettleImageInfoList())) {
                for (SignImageInfoBean settleImageInfo : settleAcctInfoBean.getSettleImageInfoList()) {
                    if (ImageTypeEnum.FUND_MANAGE.getImageType().equals(settleImageInfo.getImageType())) {
                        rglog.debug("已上传资金存管证明照片");
                        return;
                    }
                }
                rglog.error("未上传资金存管证明照片！");
            }


            //不一致查看资金管理关系证明照是否上传，未上传返回失败
            MchntImageInfoMapper mchntImageInfoMapper = new MchntImageInfoMapperImpl();
            List<MchntImageInfo> mchntImageInfoList = mchntImageInfoMapper.selectMchntImageInfoByMchntNoAndImageType(
                    mchntBaseInfo.getInstId(),
                    mchntBaseInfo.getMchntNo(),
                    ImageTypeEnum.FUND_MANAGE.getImageType());

            if (CollectionUtils.isEmpty(mchntImageInfoList)) {
                rglog.error("管理商户结算信息失败, 商户名称/商户法人跟商户结算账户户名不一致，需要上传资金管理关系证明照！，instId:{},mchntNo:{}", mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());
                throw new BizException(RespCodeEnum.PRIVATE_ENTERPRISE_LEGAL_ACCT_NAME_MATCH.getRespCode(), RespCodeEnum.PRIVATE_ENTERPRISE_LEGAL_ACCT_NAME_MATCH.getRespDesc());
            }
        }

    }


    private void modifyAcctInfoByCreateProcessing(XmlTreeUtil xmlTreeUtil, MchntSettleInfoManageRequest request, MchntBaseInfo mchntBaseInfo, MchntSignInfo mchntSignInfo) throws Exception {
        /* 修改 新增待提交或新增审核拒绝的数据 */
        String auditStatus = AuditStatusEnum.BE_AUDIT.getAuditStatus();
        String modifyTime = DateUtil.getCurrentDateTime(BompAppParamConstant.yyyy_MM_dd_HHmmssSSS);
        List<MchntAcctInfo> mchntAcctInfoList = new ArrayList<>();
        List<BizTmp> bizTmpList = new ArrayList<>();
        List<BizHistory> bizHistoryList = new ArrayList<>();

        /* 新增待提交或新增审核拒绝时，修改商户基本信息正式数据  修改是否实时清算表示，修改商户结算模式，修改商户提现标识 */
        mchntBaseInfo.setRealSettleFlag(request.getRealSettleFlag());
        mchntBaseInfo.setMchntSettleMode(request.getMchntSettleMode());
        mchntBaseInfo.setCashWithdrawalFlag(request.getCashWithdrawalFlag());
        mchntBaseInfo.setAuditStatus(auditStatus);
        mchntBaseInfo.setLastOprId(request.getUserId());

        //先查在更新，无则插入数据  （场景：之前是无需检查，现在需要检查）
        BizTmpMapper bizTmpMapper = new BizTmpMapperImpl();
        BizTmp bizTmp = bizTmpMapper.selectBizTmpByRealId(mchntBaseInfo.getInstId(), mchntBaseInfo.getId());
        if (null == bizTmp) {
            bizTmp = new BizTmp();
            ConvertUtil.convertOutput(bizTmp);
            bizTmp.setMchntName(mchntBaseInfo.getMchntName());
            bizTmp.setManageInstId(mchntBaseInfo.getSignInstId());
            bizTmp.setRealId(mchntBaseInfo.getId());
            bizTmp.setOprTableEname(TableNameConstant.T_B_MCHNT_BASE_INFO);
            bizTmp.setMasterKey(mchntBaseInfo.getId());
            bizTmp.setDetailFlag(AppParamConstant.NO);
        }

        bizTmp.setBizStatus(BizTmpStatusEnum.NO_NORMAL.getType());
        bizTmp.setBizOpr("I");
        bizTmp.setAuditStatus(auditStatus);
        String modifyMchntBaseInfoJson = JSONObject.toJSONString(mchntBaseInfo);
        InitParamUtil.initBizTempData(bizTmp, modifyMchntBaseInfoJson);
        bizTmpList.add(bizTmp);

        for (SettleAcctInfoBean settleAcctInfoBean : request.getSettleAcctInfoBeanList()) {
            //校验法人名称与结算账户名称是否一致，不一致则拒绝
            verifyMchntArtifNameAndSettleAcctName(mchntBaseInfo, mchntSignInfo, settleAcctInfoBean);

            if (BompSettleTypeEnum.STRING_SETTLE_TYPE_D0.equals(settleAcctInfoBean.getSettleType())
                    || !BompAppParamConstant.FLAG_N.equals(request.getRealSettleFlag())
                    || !BompAppParamConstant.FLAG_N.equals(request.getCashWithdrawalFlag())) {
                rglog.error("新增商户结算信息失败, 新增时结算方式不允许为D0,提现标识只能为N，instId:{},mchntNo:{}", request.getHeader().getInstId(), request.getMchntNo());
                throw new BizException(RespCodeEnum.ILLEGAL_OPERATION.getRespCode(), RespCodeEnum.ILLEGAL_OPERATION.getRespDesc());
            }

            /* 获取修改的结算信息列表 */
            getModifySettleInfoByCreateHandle(request, mchntBaseInfo, mchntAcctInfoList, bizTmpList, modifyTime, settleAcctInfoBean);
        }

        //需要审核， 更新正式表的信息为修改待审核， 将传入的商户信息更新到业务临时表
        modifyMchntAcctInfoDb(request, xmlTreeUtil, mchntBaseInfo, mchntAcctInfoList, null, bizTmpList, null);

    }


    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MchntSettleInfoManageResponse mchntSettleInfoManageResponse = (MchntSettleInfoManageResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mchntSettleInfoManageResponse);
    }

    /**
     * 结算信息-影像管理统一入口
     *
     * @param request 结算管理请求对象
     * @throws Exception 异常
     */
    private void manageSettleImageInfo(MchntSettleInfoManageRequest request) throws Exception {
        List<MchntImageInfoBean> mchntImageInfoBeanList = new ArrayList<>();
        if (CollectionUtils.isEmpty(request.getSettleAcctInfoBeanList())) {
            return;
        }
        for (SettleAcctInfoBean settleAcctInfoBean : request.getSettleAcctInfoBeanList()) {
            if (CollectionUtils.isEmpty(settleAcctInfoBean.getSettleImageInfoList())) {
                continue;
            }
            for (SignImageInfoBean signImageInfoBean : settleAcctInfoBean.getSettleImageInfoList()) {
                if (null != signImageInfoBean && !StringUtil.isEmptyOrNull(signImageInfoBean.getImageType())) {
                    MchntImageInfoBean mchntImageInfoBean = new MchntImageInfoBean();
                    mchntImageInfoBean.setImageType(signImageInfoBean.getImageType());
                    List<ImageInfoBean> imageInfoBeanList = new ArrayList<>();
                    ImageInfoBean imageInfoBean = new ImageInfoBean();
                    BeanUtil.beanCopy(signImageInfoBean, imageInfoBean);
                    imageInfoBeanList.add(imageInfoBean);
                    mchntImageInfoBean.setImageInfoList(imageInfoBeanList);
                    mchntImageInfoBeanList.add(mchntImageInfoBean);
                }
            }
        }

        if (!CollectionUtils.isEmpty(mchntImageInfoBeanList)) {
            XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
            MchntBaseInfo mchntBaseInfo = (MchntBaseInfo) xmlTreeUtil.getXmlTreeObjectValue(BompTreeNodeConstant.MCHNT_BASE_INFO, MchntBaseInfo.class);
            InitParamUtil.manageMchntImage(mchntBaseInfo, mchntImageInfoBeanList, ImageTypeEnum.SETTLE_MANAGE_IMAGE_TYPES);
        }
    }
}
